﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NLog;
using DcsGauges.Shared.DataStructures;
using System.Globalization;

namespace DcsGauges.Shared.Packets
{
    class PacketSerializer : PacketSerializationBase
    {
        private static Logger   logger                          = LogManager.GetCurrentClassLogger();
        private static Encoding encoding                        = Encoding.UTF8;

        public PacketSerializer()
	    {

	    }

        public byte[] Serialize(Packet packet)
        {
            byte[] result = null;
            if(packet.PacketType == Packet.PacketTypes.Handshake)
            {
                result = this.SerializedHandshakePacket(packet as HandshakePacket);
            }
            else if(packet.PacketType == Packet.PacketTypes.Data)
            {
                result = this.SerializedDataPacket(packet as DataPacket);
            }
            else if (packet.PacketType == Packet.PacketTypes.Commands)
            {
                result = this.SerialzeCommandsPacket(packet as CommandsPacket);
            }
            else
            {
                logger.Log(LogLevel.Warn, "Cannot serialize packet with type [{0}]", packet.GetType().FullName);
            }

            return result;
        }

        protected byte[] SerializedHandshakePacket(HandshakePacket packet)
        {
            StringBuilder packetString      = new StringBuilder(512);
            string startTag                 = GetStartTag(packet);
            string endTag                   = GetEndTag(packet);
            string content                  = packet.ClientType.ToString();
            string clientName               = packet.ClientName;

            packetString.Append(startTag).Append(content).Append(SEPERATOR).Append(clientName).Append(endTag);
            byte[] result   = encoding.GetBytes(packetString.ToString());
            return result;
        }

        protected byte[] SerializedDataPacket(DataPacket packet)
        {
            StringBuilder packetString  = new StringBuilder(1024);
            string startTag             = GetStartTag(packet);
            string endTag               = GetEndTag(packet);

            packetString.Append(startTag);

            foreach(Tuple<DcsProperty, float> v in packet.Values)
            {
                string propString       = v.Item1.Property.ToString();
                string valueString      = v.Item2.ToString(CultureInfo.InvariantCulture);
                packetString.Append(propString).Append(DataPacket.ASSIGNMENT_CHAR).Append(valueString).Append(SEPERATOR);
            }

            packetString.Remove(packetString.Length - 1, 1);
            packetString.Append(endTag);

            byte[] result   = encoding.GetBytes(packetString.ToString());
            return result;
        }

        protected byte[] SerialzeCommandsPacket(CommandsPacket packet)
        {
            StringBuilder packetString  = new StringBuilder(1024);
            string startTag             = GetStartTag(packet);
            string endTag               = GetEndTag(packet);

            packetString.Append(startTag);
            foreach (Tuple<DcsProperty, float> c in packet.Commands)
            {
                string propString       = c.Item1.Property.ToString();
                string valueString      = c.Item2.ToString(CultureInfo.InvariantCulture);
                packetString.Append(propString).Append(CommandsPacket.ASSIGNMENT_CHAR).Append(valueString).Append(SEPERATOR);
            }

            packetString.Remove(packetString.Length - 1, 1);
            packetString.Append(endTag);
            byte[] result               = encoding.GetBytes(packetString.ToString());
            return result;
        }


    }
}
